I have a list of Objects IDs dump into a file. They are out of order and i need to create a report to display the the content of those ids. I created a function to display the information that;s all good. The bad thing is that i can not get them SORT by Object Number properly. |
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) You can Google Excel sort decimal, and get lots of advice on how to sort this type of data. I also found an interesting addin at http://www.contextures.com/excel-sort-addin.html I haven't used it. A free eval copy is available. It is not very expensive either. |
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) |
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) SystemAdmin - Fri Oct 29 07:12:37 EDT 2010
I am getting crazy with those "Object Number" sorting. Can anyone please confirm, that the "lexnum" stuff and other simple padding algorithms of object number do NOT work as expected on this kind of Module Structure:
Object Level Object Number Heading / Text
1 1 Heading
2 1.1 Heading
1 <- no typo! 1-1 Text
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
|
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) Mathias Mamsch - Tue Jan 25 10:17:31 EST 2011
I am getting crazy with those "Object Number" sorting. Can anyone please confirm, that the "lexnum" stuff and other simple padding algorithms of object number do NOT work as expected on this kind of Module Structure:
Object Level Object Number Heading / Text
1 1 Heading
2 1.1 Heading
1 <- no typo! 1-1 Text
Mathias Mamsch, IT-QBase GmbH, Consultant for Requirement Engineering and D00RS
I'm not seeing the problem. ... snip ... investigate ... OK, now I indeed see the problem; it occurs when a text object is placed after a sibling Heading object. So I fixed my functions, which I now defy anybody to show a situation where the displayed objects are not in fact in the same order as shown in the Standard View.
//**************
bool not(bool InBool)
{ // Invert the input boolean.
// This allows other scripts to write things like:
// if (not CheckResults), rather than
// if (! CheckResults)
// When combined with "or" and "and", it makes Boolean expressions easier to read.
return(!InBool)
} // end not()
const string cl_fPadParaZeros = "0000000000"
Buffer gl_bufPadOut = create() // Internal buffer for the following fPadPara and fPadID
//******************
string fPadPara(string ParaNum, int NumDigits)
{ // Pad each numeric field of the Para Number with leading Zeros.
// i.e. if "NumDigits" is 3 then convert
// "3.2.3-0.29.4444" to "003,002,003-000,029,4444"
// This is useful before sorting paragraph numbers alpha-numerically
// See sister function "fUnPadPara()"
// NumDigits must be <= 10 (defined length of cl_fPadParaZeros)
// Note that legal paragraph numbers have delimiters "." and "-".
// Since the dash '-' sorts before a period '.', sorting fails when
// a text object follows a sibling Heading object.
// Thus the period is replaced with a comma ',' to support sorting,
// and comma's are replaced back to periods in sibling fUnPadPara() below.
int Start, End // Bounds of each number field; either pointing
// to the Delimiters or the beginning or end of
// ParaNum
int LenPara = length(ParaNum)
string SubStr // Part between Delimiters (a number field)
int LenSub // length of SubString
char Delim // Actual Delimiter.
if (LenPara <= 0) return("")
gl_bufPadOut = ""
Start = -1
while (Start < LenPara)
{ Delim = null
// Find the next SubString, which is between'
// the legal Paragraph Delimiters "." and "-".
for (End = Start+1; End < LenPara; End++)
{ if (ParaNum[End] == '.' or
ParaNum[End] == ',' or
ParaNum[End] == '-')
{ Delim = ParaNum[End]
break
}
}
if (Delim == '.') then Delim = ','
// End now points to the next Delimiter or is
// beyond the end of ParaNum
SubStr = ParaNum[Start+1:End-1]
LenSub = length(SubStr)
if (NumDigits-LenSub-1 >=0)
gl_bufPadOut += cl_fPadParaZeros[0:NumDigits-LenSub-1] // Pad with Zeros
gl_bufPadOut += SubStr
if (not null Delim) gl_bufPadOut += Delim
// print Start "\t" End "\t'" SubStr "'\n"
Start = End // Reposition for next pass
} // end while more ParaNum to parse.
return(stringOf(gl_bufPadOut))
} // end fPadPara()
//************************
string fUnPadPara(string ParaNum)
{ // Strip the padding inserted by sibling function "fPadPara()".
// I.E. convert "003,002,003-000.029.4444" to "3.2.3-0.29.4444"
// Note that at least one digit will remain (the zero in '0.29')
int Start, End // Positions of . or - in ParaNum.
int LenPara = length(ParaNum)
char Delim
bool UnPad
gl_bufPadOut = ""
Start = -1
while (Start < LenPara)
{ Delim = null
UnPad = true
for (End = Start+1; End < LenPara; End++)
{ // Strip all leading Zeros; which means stop UnPadding
// when the first non-Zero character is encountered.
if (UnPad and ParaNum[End] == '0')
Start = End
else {UnPad = false}
if (ParaNum[End] == '.' or
ParaNum[End] == ',' or
ParaNum[End] == '-')
{ Delim = ParaNum[End]
break
}
} // End found Delim or end of ParaNum
if (Delim == ',') then Delim = '.'
// print Start "\t" End "\t" "\n"
if (Start+1 > End-1)
Start-- // Allow last Zero
gl_bufPadOut += ParaNum[Start+1:End-1]
if (not null Delim) gl_bufPadOut += Delim
Start = End
} // end while more ParaNum to Parse
return(stringOf(gl_bufPadOut))
} // end fUnPadPara()
// ********** BEGIN MAIN Testing *****************
Skip skp = createString() // KEY 'string' ID; DATA 'string' Padded para num
string ParaYesPadded, ParaNotPadded, ID
Object obj
for obj in (current Module) do
{ ParaNotPadded = number(obj)
ParaYesPadded = fPadPara(ParaNotPadded, 3)
put(skp, ParaYesPadded, identifier(obj))
}
for ID in skp do
{ ParaYesPadded = (string key skp)
ParaNotPadded = fUnPadPara(ParaYesPadded)
print ID " \t" ParaNotPadded "\t\t[" ParaYesPadded "]\n"
}
delete(skp)
|
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) llandale - Tue Jan 25 12:58:03 EST 2011 I'm not seeing the problem. ... snip ... investigate ... OK, now I indeed see the problem; it occurs when a text object is placed after a sibling Heading object. So I fixed my functions, which I now defy anybody to show a situation where the displayed objects are not in fact in the same order as shown in the Standard View.
//**************
bool not(bool InBool)
{ // Invert the input boolean.
// This allows other scripts to write things like:
// if (not CheckResults), rather than
// if (! CheckResults)
// When combined with "or" and "and", it makes Boolean expressions easier to read.
return(!InBool)
} // end not()
const string cl_fPadParaZeros = "0000000000"
Buffer gl_bufPadOut = create() // Internal buffer for the following fPadPara and fPadID
//******************
string fPadPara(string ParaNum, int NumDigits)
{ // Pad each numeric field of the Para Number with leading Zeros.
// i.e. if "NumDigits" is 3 then convert
// "3.2.3-0.29.4444" to "003,002,003-000,029,4444"
// This is useful before sorting paragraph numbers alpha-numerically
// See sister function "fUnPadPara()"
// NumDigits must be <= 10 (defined length of cl_fPadParaZeros)
// Note that legal paragraph numbers have delimiters "." and "-".
// Since the dash '-' sorts before a period '.', sorting fails when
// a text object follows a sibling Heading object.
// Thus the period is replaced with a comma ',' to support sorting,
// and comma's are replaced back to periods in sibling fUnPadPara() below.
int Start, End // Bounds of each number field; either pointing
// to the Delimiters or the beginning or end of
// ParaNum
int LenPara = length(ParaNum)
string SubStr // Part between Delimiters (a number field)
int LenSub // length of SubString
char Delim // Actual Delimiter.
if (LenPara <= 0) return("")
gl_bufPadOut = ""
Start = -1
while (Start < LenPara)
{ Delim = null
// Find the next SubString, which is between'
// the legal Paragraph Delimiters "." and "-".
for (End = Start+1; End < LenPara; End++)
{ if (ParaNum[End] == '.' or
ParaNum[End] == ',' or
ParaNum[End] == '-')
{ Delim = ParaNum[End]
break
}
}
if (Delim == '.') then Delim = ','
// End now points to the next Delimiter or is
// beyond the end of ParaNum
SubStr = ParaNum[Start+1:End-1]
LenSub = length(SubStr)
if (NumDigits-LenSub-1 >=0)
gl_bufPadOut += cl_fPadParaZeros[0:NumDigits-LenSub-1] // Pad with Zeros
gl_bufPadOut += SubStr
if (not null Delim) gl_bufPadOut += Delim
// print Start "\t" End "\t'" SubStr "'\n"
Start = End // Reposition for next pass
} // end while more ParaNum to parse.
return(stringOf(gl_bufPadOut))
} // end fPadPara()
//************************
string fUnPadPara(string ParaNum)
{ // Strip the padding inserted by sibling function "fPadPara()".
// I.E. convert "003,002,003-000.029.4444" to "3.2.3-0.29.4444"
// Note that at least one digit will remain (the zero in '0.29')
int Start, End // Positions of . or - in ParaNum.
int LenPara = length(ParaNum)
char Delim
bool UnPad
gl_bufPadOut = ""
Start = -1
while (Start < LenPara)
{ Delim = null
UnPad = true
for (End = Start+1; End < LenPara; End++)
{ // Strip all leading Zeros; which means stop UnPadding
// when the first non-Zero character is encountered.
if (UnPad and ParaNum[End] == '0')
Start = End
else {UnPad = false}
if (ParaNum[End] == '.' or
ParaNum[End] == ',' or
ParaNum[End] == '-')
{ Delim = ParaNum[End]
break
}
} // End found Delim or end of ParaNum
if (Delim == ',') then Delim = '.'
// print Start "\t" End "\t" "\n"
if (Start+1 > End-1)
Start-- // Allow last Zero
gl_bufPadOut += ParaNum[Start+1:End-1]
if (not null Delim) gl_bufPadOut += Delim
Start = End
} // end while more ParaNum to Parse
return(stringOf(gl_bufPadOut))
} // end fUnPadPara()
// ********** BEGIN MAIN Testing *****************
Skip skp = createString() // KEY 'string' ID; DATA 'string' Padded para num
string ParaYesPadded, ParaNotPadded, ID
Object obj
for obj in (current Module) do
{ ParaNotPadded = number(obj)
ParaYesPadded = fPadPara(ParaNotPadded, 3)
put(skp, ParaYesPadded, identifier(obj))
}
for ID in skp do
{ ParaYesPadded = (string key skp)
ParaNotPadded = fUnPadPara(ParaYesPadded)
print ID " \t" ParaNotPadded "\t\t[" ParaYesPadded "]\n"
}
delete(skp)
|
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) Mathias Mamsch - Wed Jan 26 13:02:36 EST 2011
This is a great code, now i need to sort all in a ListView Column.
DB win
DBE lv
Skip sortSkip = createString
string arr[6] = {"3.1-2","1.3","3.1-1","1.2.3","1.10","2.3.4.5"}
string getNextEnumeratedValue(string &sEnumerated, Regexp reg) {
string result
if (!reg sEnumerated) {
sEnumerated = ""
return ""
}
result = sEnumerated[0: (start 0)-1]
sEnumerated = sEnumerated[end 0 +1:]
return result
} // end getNextEnumeratedValue
int sReqLoop(string a, string b){
return 0
}
int sReqWoot(string a, string b){
Regexp reg = regexp "(\\.|-)"
string atemp = a
string btemp = b
string ap, bp
int iap, ibp
while(atemp != ""){
if(isValidInt(atemp)){
iap = intOf atemp
ap = atemp
atemp = null
}
else{
ap = getNextEnumeratedValue(atemp, reg)
iap = intOf ap
}
if(isValidInt(btemp)){
ibp = intOf btemp
bp = btemp
btemp = null
}
else{
bp = getNextEnumeratedValue(btemp, reg)
ibp = intOf bp
}
if(iap > ibp)
return 1
else if(ibp > iap)
return -1
}
return 0
}
win = centered("Testing Sorting")
lv = listView(win,listViewOptionSortText,200, 10, arr)
realize(win)
insertColumn(lv,0,"Lista", 85, iconNone)
set(lv, 0, sReqWoot)
show(win)
|
Re: Creating a script to reconcile identifiers by Object Number (number(obj)) llandale - Tue Jan 25 12:58:03 EST 2011 I'm not seeing the problem. ... snip ... investigate ... OK, now I indeed see the problem; it occurs when a text object is placed after a sibling Heading object. So I fixed my functions, which I now defy anybody to show a situation where the displayed objects are not in fact in the same order as shown in the Standard View.
//**************
bool not(bool InBool)
{ // Invert the input boolean.
// This allows other scripts to write things like:
// if (not CheckResults), rather than
// if (! CheckResults)
// When combined with "or" and "and", it makes Boolean expressions easier to read.
return(!InBool)
} // end not()
const string cl_fPadParaZeros = "0000000000"
Buffer gl_bufPadOut = create() // Internal buffer for the following fPadPara and fPadID
//******************
string fPadPara(string ParaNum, int NumDigits)
{ // Pad each numeric field of the Para Number with leading Zeros.
// i.e. if "NumDigits" is 3 then convert
// "3.2.3-0.29.4444" to "003,002,003-000,029,4444"
// This is useful before sorting paragraph numbers alpha-numerically
// See sister function "fUnPadPara()"
// NumDigits must be <= 10 (defined length of cl_fPadParaZeros)
// Note that legal paragraph numbers have delimiters "." and "-".
// Since the dash '-' sorts before a period '.', sorting fails when
// a text object follows a sibling Heading object.
// Thus the period is replaced with a comma ',' to support sorting,
// and comma's are replaced back to periods in sibling fUnPadPara() below.
int Start, End // Bounds of each number field; either pointing
// to the Delimiters or the beginning or end of
// ParaNum
int LenPara = length(ParaNum)
string SubStr // Part between Delimiters (a number field)
int LenSub // length of SubString
char Delim // Actual Delimiter.
if (LenPara <= 0) return("")
gl_bufPadOut = ""
Start = -1
while (Start < LenPara)
{ Delim = null
// Find the next SubString, which is between'
// the legal Paragraph Delimiters "." and "-".
for (End = Start+1; End < LenPara; End++)
{ if (ParaNum[End] == '.' or
ParaNum[End] == ',' or
ParaNum[End] == '-')
{ Delim = ParaNum[End]
break
}
}
if (Delim == '.') then Delim = ','
// End now points to the next Delimiter or is
// beyond the end of ParaNum
SubStr = ParaNum[Start+1:End-1]
LenSub = length(SubStr)
if (NumDigits-LenSub-1 >=0)
gl_bufPadOut += cl_fPadParaZeros[0:NumDigits-LenSub-1] // Pad with Zeros
gl_bufPadOut += SubStr
if (not null Delim) gl_bufPadOut += Delim
// print Start "\t" End "\t'" SubStr "'\n"
Start = End // Reposition for next pass
} // end while more ParaNum to parse.
return(stringOf(gl_bufPadOut))
} // end fPadPara()
//************************
string fUnPadPara(string ParaNum)
{ // Strip the padding inserted by sibling function "fPadPara()".
// I.E. convert "003,002,003-000.029.4444" to "3.2.3-0.29.4444"
// Note that at least one digit will remain (the zero in '0.29')
int Start, End // Positions of . or - in ParaNum.
int LenPara = length(ParaNum)
char Delim
bool UnPad
gl_bufPadOut = ""
Start = -1
while (Start < LenPara)
{ Delim = null
UnPad = true
for (End = Start+1; End < LenPara; End++)
{ // Strip all leading Zeros; which means stop UnPadding
// when the first non-Zero character is encountered.
if (UnPad and ParaNum[End] == '0')
Start = End
else {UnPad = false}
if (ParaNum[End] == '.' or
ParaNum[End] == ',' or
ParaNum[End] == '-')
{ Delim = ParaNum[End]
break
}
} // End found Delim or end of ParaNum
if (Delim == ',') then Delim = '.'
// print Start "\t" End "\t" "\n"
if (Start+1 > End-1)
Start-- // Allow last Zero
gl_bufPadOut += ParaNum[Start+1:End-1]
if (not null Delim) gl_bufPadOut += Delim
Start = End
} // end while more ParaNum to Parse
return(stringOf(gl_bufPadOut))
} // end fUnPadPara()
// ********** BEGIN MAIN Testing *****************
Skip skp = createString() // KEY 'string' ID; DATA 'string' Padded para num
string ParaYesPadded, ParaNotPadded, ID
Object obj
for obj in (current Module) do
{ ParaNotPadded = number(obj)
ParaYesPadded = fPadPara(ParaNotPadded, 3)
put(skp, ParaYesPadded, identifier(obj))
}
for ID in skp do
{ ParaYesPadded = (string key skp)
ParaNotPadded = fUnPadPara(ParaYesPadded)
print ID " \t" ParaNotPadded "\t\t[" ParaYesPadded "]\n"
}
delete(skp)
But also "a" "b" "A" "B" sorts as "a" "A" "b" "B"... Why????? I fixed the duplicate script with the following padding script, which is basically functionally equivalent to the one from Louie above, but shorter. Only changes it that it uses "_" iso "," because that is sorted before "-" string pad(string num, int digits) { int start = 0, end = 0 num = num "." char d string r = "" int lnum = length(num) while (end < lnum) { d = numend if (d == '.' || d == ',' || d == '-') { if (d == '.') d = '_' r = r ZEROS0:digits-end+start-1 numstart:end-1 d "" start = end + 1 n = 0 } end++ } return r0:length(r)-2 } // end pad() |